package com.huzz.util.entityutil;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;


/**
* 相似实体类数据类型的转换
* @author 童年的纸飞机
* @created 2021-12-07 9:55
*/
@Component
public class ModelUtil<Source, Target> {

    private static final Logger log = LoggerFactory.getLogger(ModelUtil.class);

    /**
    * 通过静态方法调用(单例模式)
    */
    private static ModelUtil modelUtil = new ModelUtil();

    public ModelUtil(){

    }

    /** -----------------------静态方法方式调用-------------------------------------- */
    /**
    * 转换为目标对象
    * @param from 源对象
    * @param to 目标对象类
    * @return 目标对象
    */
    public static<Target> Target transToSimilarEntity(Object from, Class<Target> to){
        return (Target) modelUtil.toSimilarEntity(from, to);
    }

    /**
    * 转换为目标Page对象
    * @param from 源对象
    * @param to 目标类型
    * @return 目标Page对象
    */
    public static<Target> IPage<Target> transToSimilarPage(IPage<?> from, Class<Target> to){
        return modelUtil.toSimilarPage(from, to);
    }

    /**
    * 转换为目标List对象
    * @param from 源对象
    * @param to 目标类型
    * @return 目标List对象
    */
    public static<Target> List<Target> transToSimilarList(List<?> from, Class<Target> to){
        return modelUtil.toSimilarList(from, to);
    }
    /** -------------------------------------------------------------------------- */

    /**
    * 转换为实体对象
    *
    * @return Target
    */
    public Target toSimilarEntity(Source source, Class<Target> type) {
        Target target = createInstance(type);
        BeanUtils.copyProperties(source, target);
        return target;
    }

    /**
    * 实例化对象
    *
    * @param clazz
    * @return
    */
    private Target createInstance(Class<Target> clazz) {
        Target target = null;
        try {
            target = clazz.newInstance();
        } catch (InstantiationException e) {
            log.info("转换为实体对象错误: 实例化{}失败", clazz);
            e.getMessage();
        } catch (IllegalAccessException e) {
            log.info("转换为实体对象错误: 无权访问指定类{}", clazz);
            e.getMessage();
        }
            return target;
    }

    /**
    * Page类型entity转换
    * @param source
    * @param type
    * @return
    */
    public IPage<Target> toSimilarPage(IPage<Source> source, Class<Target> type) {
        IPage<Target> target = new Page<>();
        BeanUtils.copyProperties(source, target);
        target.setRecords(toSimilarList(source.getRecords(), type));

        return target;
    }

    /**
    * List类型的数据entity转换
    * @param source
    * @param type
    * @return
    */
    private List<Target> toSimilarList(List<Source> source, Class<Target> type) {
        List<Target> target = new ArrayList<>();
        source.forEach(e -> {
            Target instance = createInstance(type);
            BeanUtils.copyProperties(e, instance);
            target.add(instance);
        });

        return target;
    }

}
